package com.test.auth_db_auto.auth_sms;

import com.test.auth_db_auto.mapper.UserMapper;
import com.test.auth_db_auto.model.User;
import com.test.auth_db_auto.support.SmsUserDetailService;
import com.test.auth_db_auto.utils.RedisUtil;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import java.util.UUID;

/**
 * @ Author: .Mr
 * @ ClassName SmsAuthenticationProvider
 * @ Description TODO
 * @ date 2022/1/4 17:23
 * @ Version 1.0
 * 自定义手机号短息用户验证
 */
@Getter
@Setter
public class SmsAuthenticationProvider implements AuthenticationProvider {

    private SmsUserDetailService userDetailsService;

    public SmsAuthenticationProvider(){}


    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        SmsCodeAuthenticationToken authenticationToken=(SmsCodeAuthenticationToken)authentication;
        String mobile=authenticationToken.getPrincipal().toString();
        //校验手机号
        UserDetails details = this.userDetailsService.loadUserByUsername(mobile);

        if(details==null){
            //新用户，得设置密码
            String password=authenticationToken.getPassword();
            if(password.equals("")){
                String uuId= UUID.randomUUID().toString().replace("-","");
                RedisUtil.set("account:check:"+mobile,uuId,300);
                throw new InternalAuthenticationServiceException("用户需要设置密码(唯一标识):"+uuId);
            }else{
                if(!RedisUtil.hasKey("account:check:"+mobile)){
                    throw new InternalAuthenticationServiceException("无法获取用户信息");
                }

                String checkInfo=RedisUtil.get("account:check:"+mobile).toString();
                if(!checkInfo.equals(authenticationToken.getExamine())){
                    throw new InternalAuthenticationServiceException("无法获取用户信息");
                }

                User user=new User();
                user.setUsername(mobile);
                user.setMobile(mobile);
                user.setIsEnable(true);
                user.setIsExpired(false);
                user.setIsLocked(true);
                user.setPassword(new BCryptPasswordEncoder().encode(password));
               int num =userDetailsService.insertInfo(user);
                if(num==1){
                    details = this.userDetailsService.loadUserByUsername(mobile);
                }else{
                    throw new InternalAuthenticationServiceException("系统有误");
                }
            }
        }

        //验证成功了
        SmsCodeAuthenticationToken authenticationResult = new SmsCodeAuthenticationToken(details, details.getAuthorities());

        authenticationResult.setDetails(authenticationToken);
        return authenticationResult;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        //该SmsCodeAuthenticationProvider只支持SmsCodeAuthenticationToken的token认证
        return SmsCodeAuthenticationToken.class.isAssignableFrom(authentication);
    }

}
